package com.atguigu.srb.sms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.common.exception.BusinessException;
import com.atguigu.common.results.R;
import com.atguigu.common.results.ResultCodeEnum;
import com.atguigu.common.utils.HttpUtils;
import com.atguigu.common.utils.RandomUtils;
import com.atguigu.common.utils.RegexValidateUtils;
import com.atguigu.srb.sms.feign.ServiceCoreClient;
import com.atguigu.srb.sms.service.SmsService;
import com.atguigu.srb.sms.utils.SmsProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SmsServiceImpl implements SmsService {
    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    ServiceCoreClient serviceCoreClient;
    @Override
    public void sendNotifyMsg(String mobile, String content){
        try {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", "APPCODE " + SmsProperties.APP_CODE);
            //请求参数：
            Map<String, String> querys = new HashMap<String, String>();
            querys.put("mobile", mobile);
            querys.put("param", "code:"+content);
            querys.put("tpl_id", SmsProperties.REGISTE_TPLID);//短信模板id： 在短信运营商服务器中对应了一个短信字符串
            //请求体
            Map<String, String> bodys = new HashMap<String, String>();
            HttpResponse response = HttpUtils
                    .doPost(SmsProperties.HOST, SmsProperties.PATH, SmsProperties.METHOD,
                            headers, querys, bodys);

            String body = EntityUtils.toString(response.getEntity(),"UTF-8");
            //将响应的json转为map
            Map map = JSON.parseObject(body, Map.class);
            String returnCode = map.get("return_code").toString();

            log.info("短信发送结果：{}",JSON.toJSONString(map));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void sendMsg(String mobile, Integer type) {
        //1、校验参数:正则校验手机号码格式
        boolean b = RegexValidateUtils.checkCellphone(mobile);
        if(!b){
            //手机号码格式错误
            throw new BusinessException(ResultCodeEnum.MOBILE_ERROR);
        }
        //手机号是否已注册
        R r = serviceCoreClient.isRegisted(mobile);
//        serviceCoreClient.test1(R.success().message("canshu1"));
//        serviceCoreClient.test2("admin","123456");
//        serviceCoreClient.test3(R.success().message("test3canshu"));
        if(r.getCode()!=0 || !(Boolean)(r.getData().get("flag"))){
            //请求失败或者 手机号码被占用
            throw new BusinessException(ResultCodeEnum.MOBILE_EXIST_ERROR);
        }
        //2、校验该手机号码发送验证码的频率
        //两分钟只能获取一次
        if(redisTemplate.hasKey("sms:min:times:"+ mobile)){
            throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
        }
        //一天只能获取5次
        if(!redisTemplate.hasKey("sms:day:times:"+ mobile)){
            redisTemplate.opsForValue().set("sms:day:times:"+ mobile , "0" ,
                    24 , TimeUnit.HOURS );
        }else{
            int count = Integer.parseInt(redisTemplate.opsForValue().get("sms:day:times:"+ mobile));
            if(count>=5){
                throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_LIMIT_DAY_ERROR);
            }
        }
        //3、发送验证码
        String returnCode = null; //短信发送返回的状态码
        String body = null;//短信发送返回的响应体内容
        String code = null;
        try {
            //生成验证码 判断使用哪个短信模板
            code = RandomUtils.getFourBitRandom();
            String tplId = null;
            // type = 1 注册   2 登录密码  3 借款审核通过  默认 1
            switch (type){
                case 2:
                    tplId = SmsProperties.AUTH_TPLID;
                    break;
                case 3:
                    tplId = SmsProperties.AUTH_TPLID;
                    break;
                default:
                    tplId = SmsProperties.REGISTE_TPLID;
            }
            //调用第三方api发送短信
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", "APPCODE " + SmsProperties.APP_CODE);
            //请求参数：
            Map<String, String> querys = new HashMap<String, String>();
            querys.put("mobile", mobile);
            querys.put("param", "code:"+code);
            querys.put("tpl_id", tplId);//短信模板id： 在短信运营商服务器中对应了一个短信字符串
            //请求体
            Map<String, String> bodys = new HashMap<String, String>();
//            HttpResponse response = HttpUtils
//                    .doPost(SmsProperties.HOST, SmsProperties.PATH, SmsProperties.METHOD,
//                            headers, querys, bodys);

//            body = EntityUtils.toString(response.getEntity(),"UTF-8");
            //将响应的json转为map
//            Map map = JSON.parseObject(body, Map.class);
//            returnCode = map.get("return_code").toString();

        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_NET_ERROR);
        }
//        if(!"00000".equals(returnCode)){
//            //System.out.println("短信发送失败："+ map);
//            log.error("短信发送失败: {}" , body);
//            throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_ERROR);
//        }
        //4、保存验证码到redis中
        //短信发送成功：将验证码缓存到redis中 过期时间10分钟
        // 每个用户手机号码唯一
        redisTemplate.opsForValue().set("sms:code:"+ mobile , code ,
                10 , TimeUnit.MINUTES);
        //5、更新验证码获取的频率
        //2分钟不能重复获取： 使用该手机号码拼接唯一的key存到redis过期时间2分钟
        redisTemplate.opsForValue().set("sms:min:times:"+ mobile, "1",
                3 , TimeUnit.MINUTES);
        //一天内只能获取5次验证码
        //在验证码次数的基础上+1
        redisTemplate.opsForValue().increment("sms:day:times:"+ mobile);

    }
}
